//
//  PYCHZWithMultiPYsInspector.m
//  PinyinContacts
//
//  Created by Xiaoping Zhang on 2/20/10.
//  Copyright 2010 Filters, Inc. All rights reserved.
//

#import "PYCHZWithMultiPYsInspectorController.h"
#import "PYCHZWithMultiPYs.h"

static NSString *kIndexColumnIdentifier = @"indexColumn";
static NSString *kHanziColumnIdentifier = @"hanziColumn";
static NSString *kPinyinColumnIdentifier = @"pinyinColumn";

@implementation PYCHZWithMultiPYsInspectorController

#pragma mark Initializer and dealloc

- (id) initWithObjectContext:(NSManagedObjectContext *)objectContext
{
	if (objectContext == nil)
		return nil;
	
	self = [super initWithWindowNibName:@"PYCHZWithMultiPYsInspector"];
	
	[self setHzPYDBContext:objectContext];
	isPopulated = NO;
	
	return self;
}

- (void)dealloc
{
	[super dealloc];
}

#pragma mark --
#pragma mark Table delegate

- (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
	id identifier = [tableColumn identifier];
	if (!identifier || ![identifier isKindOfClass:[NSString class]])
		return nil;
	
	NSCell *originalCell = [tableColumn dataCell];
	if (![identifier isEqualToString:kPinyinColumnIdentifier])
	{
		return originalCell;
	}
	
	if (!isPopulated)
	{
		return originalCell;
	}
	
	assert(filteredContent && [filteredContent count] > 0);
	if (!filteredContent || [filteredContent count] == 0)
		return originalCell;

	NSPopUpButtonCell *popupButtonCell = [[[NSPopUpButtonCell alloc] initTextCell:@""] autorelease];;
	NSMenu *menu = [popupButtonCell menu];
	
	[popupButtonCell setEditable:YES];  /* This table column must be set to not editable in IB.  */
	[popupButtonCell setBordered:NO];
	NSMenuItem *menuItem = nil;
	
	PYCHZWithMultiPYs *currentHZ = [filteredContent objectAtIndex:row];
	NSArray *pinyinList = [currentHZ pinyinList];

	for (NSString *pinyinString in pinyinList)
	{
		menuItem = [[NSMenuItem alloc] initWithTitle:pinyinString action:nil keyEquivalent:[NSString string]];
		[menu addItem:[menuItem autorelease]];
	}
	
	return popupButtonCell;
}

#pragma mark --

#pragma mark Table data source

- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
{
	if (!isPopulated)
		return nil;
	
	unichar buffer[4];
	
	id hzpy = [[self filteredContent] objectAtIndex:rowIndex];
	
	if (!hzpy)
		return nil;
	
	id columnIdentifier = [aTableColumn identifier];
	if (!columnIdentifier || ![columnIdentifier isKindOfClass:[NSString class]])
	{
		return nil;
	}
	
	NSString *columnIdentifierString = (NSString *)columnIdentifier;
	id value = nil;
	
	if ([columnIdentifierString isEqualToString:kIndexColumnIdentifier])
	{
		value = [NSNumber numberWithInt:rowIndex + 1];
	}
	else if ([columnIdentifierString isEqualToString:kHanziColumnIdentifier])
	{
		if ([hzpy respondsToSelector:@selector(hanzi)])
		{
			value = [hzpy hanzi];
			[value getCharacters:buffer];
		}
	}
	else if ([columnIdentifierString isEqualToString:kPinyinColumnIdentifier])
	{
		if ([hzpy respondsToSelector:@selector(primaryPYIndex)])
		{
			value = [NSNumber numberWithUnsignedInt:[hzpy primaryPYIndex]];
		}
	}
	
	return value;
}

- (void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
	if (!object || !isPopulated)
		return;
	
	id hzpy = [filteredContent objectAtIndex:row];
	if (!hzpy)
		return;
	
	id columnIdentifier = [tableColumn identifier];
	if (!columnIdentifier || ![columnIdentifier isKindOfClass:[NSString class]])
	{
		return;
	}
	
	NSString *columnIdentifierString = (NSString *)columnIdentifier;
	
	if ([columnIdentifierString isEqualToString:kPinyinColumnIdentifier])
	{
		if ([object isKindOfClass:[NSNumber class]] &&
			[hzpy respondsToSelector:@selector(setPrimaryPYIndex:)])
		{
			[hzpy setPrimaryPYIndex:[object unsignedIntValue]];
		}
	}
	else if ([columnIdentifierString isEqualToString:kHanziColumnIdentifier])
	{
		if ([object isKindOfClass:[NSString class]] &&
			[hzpy respondsToSelector:@selector(setHanzi:)])
		{
			[hzpy setHanzi:object];
		}
	}
	
	return;
}

#pragma mark --
#pragma mark Overloaded methods

- (void) retrievingThreadMethod
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	
	[self performSelectorOnMainThread:@selector(updateProgress:) withObject:[NSNumber numberWithInt:0] waitUntilDone:YES];
	
	NSArray *allCharacters = [self retrieveAllCharacters];
	[self setUnfilteredContent:[NSMutableArray array]];
	[self setFilteredContent:nil];
	
	// Increase retain count in order to avoid filteredContent to be deallocated in dealloc method.
	//[filteredContent retain];
	
	NSUInteger hzpyCount = [allCharacters count];
	NSUInteger currentIndex = 0;
	
	while (![[NSThread currentThread] isCancelled] && hzpyCount > 1 && currentIndex < hzpyCount)
	{
		PYCHzpy *next = nil, *current = nil;

		current = [allCharacters objectAtIndex:currentIndex];
		// Aways set next to nil
		next = nil;
		
		if (currentIndex < hzpyCount - 1)
		{
			next = [allCharacters objectAtIndex:(currentIndex + 1)];
		}
		
		if (next && [[current hanzi] isEqualToString:[next hanzi]])
		{
			//[filteredContent addObject:current];
			PYCHZWithMultiPYs *hzpy = [[PYCHZWithMultiPYs alloc] initWithHanzi:[current hanzi]];
			
			assert(hzpy);
			[hzpy addPinyin:current];
			[hzpy addPinyin:next];
			currentIndex = currentIndex + 2;
			
			[unfilteredContent addObject:hzpy];
			
			while (currentIndex < hzpyCount)
			{
				next = [allCharacters objectAtIndex:currentIndex];
				if (next && [[current hanzi] isEqualToString:[next hanzi]])
				{
					[hzpy addPinyin:next];
					++currentIndex;
				}
				else 
				{
					break;
				}
			}
		}
		else 
		{
			++currentIndex;
		}
	}
	
	// Normolize data
	for (PYCHZWithMultiPYs *item in unfilteredContent)
	{
		[item normalize];
	}
	
	NSError *error;
	
	if (![hzPYDBContext save:&error])
	{
		NSLog(@"Error while saving content: %@", [error localizedDescription]);
	}
	
	[self setFilteredContent:[NSMutableArray arrayWithArray:unfilteredContent]];
	
	[self performSelectorOnMainThread:@selector(updateProgress:) withObject:[NSNumber numberWithInt:100] waitUntilDone:YES];
	
	[retrievingThread release];
	retrievingThread = nil;
	
	[pool release];
}

- (void)searchTextChanged:(NSNotification *)note
{
	NSString *searchText = [searchField stringValue];
	
	if (searchText == nil || [searchText length] == 0)
	{
		[self setFilteredContent:[NSMutableArray arrayWithArray:unfilteredContent]];
	}
	else 
	{
		NSPredicate *predicate = [NSPredicate predicateWithFormat:@"hanzi = %@", searchText];
		
		NSArray *resultArray = [unfilteredContent filteredArrayUsingPredicate:predicate];
		[self setFilteredContent:[NSMutableArray arrayWithArray:resultArray]];
	}
	
	[tableView reloadData];
}

- (void)deleteSheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
{
	if (NSAlertFirstButtonReturn != returnCode)
	{
		return;
	}
	
	NSIndexSet *selectedIndexes = [tableView selectedRowIndexes];
	if (selectedIndexes == nil || [selectedIndexes count] == 0)
	{
		return;
	}
	
	NSUInteger currentIndex = [selectedIndexes firstIndex];
	NSMutableArray *itemsToDelete = [NSMutableArray array];
	
	while (currentIndex != NSNotFound)
	{
		PYCHZWithMultiPYs * currentObject = [filteredContent objectAtIndex:currentIndex];
		
		[currentObject deleteFromContext:hzPYDBContext];

		currentIndex = [selectedIndexes indexGreaterThanIndex:currentIndex];		
		[itemsToDelete addObject:currentObject];
	}
	
	NSError *error;
	
	if (![hzPYDBContext save:&error])
	{
		NSLog(@"Error while saving: %@", [error localizedDescription]);
		return;
	}
	
	[filteredContent removeObjectsAtIndexes:selectedIndexes];
	[unfilteredContent removeObjectsInArray:itemsToDelete];
	
	[tableView reloadData];
	
	[self performSelector:@selector(updateTableSelection:) withObject:[[NSNumber numberWithUnsignedInt:[selectedIndexes lastIndex]] retain] afterDelay:0];
}

@end
